package com.letoken.platform.pub.advice;



import com.letoken.platform.pub.enums.ApiResponseEnum;
import com.letoken.platform.pub.enums.LetokenApiResponseEnum;
import com.letoken.platform.pub.exception.ApiServiceException;
import com.letoken.platform.pub.message.LocaleMessage;
import com.letoken.platform.pub.res.ApiResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.base.BaseLocal;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.dao.DataAccessException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.support.RequestContextUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.sql.SQLException;
import java.util.List;
import java.util.Locale;

/**
 * ApiServiceExceptionHandler
 *
 * @Author: letokenlabs
 * @Date: 2021/11/23 15:02
 */
@Slf4j
@RestControllerAdvice(annotations = {RestController.class})
public class ApiServiceExceptionHandler {

    @Resource
    private LocaleMessage resultCodeLocaleMessage;


    @ExceptionHandler({ApiServiceException.class})
    public ApiResponse handleServiceException(HttpServletRequest req, final ApiServiceException e) {
        log.error(e.getMessage(),e);
//        return ApiResponse.create(e.getCode(), resultCodeLocaleMessage.getMessage(e.getCode(),new Object[0], RequestContextUtils.getLocale(req)));

        String desc = resultCodeLocaleMessage.getMessage(e.getCode(),null,null,getLocal());
        if (StringUtils.isBlank(desc)){
            if (StringUtils.isBlank(e.getDesc())){
                return ApiResponse.create(e.getCode(), e.getMessage());
            }
            return ApiResponse.create(e.getCode(), e.getDesc());
        }

        if (desc.contains("s%")){
            Object[] arr = e.getArgs();
            desc = String.format(desc,arr);
        }

        return ApiResponse.create(e.getCode(),desc );
    }

    /**
     * 参数校验异常拦截
     *
     * @param e
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ApiResponse handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error(e.getMessage(),e);
        BindingResult bindingResult = e.getBindingResult();
        ObjectError firstError = null;
        if (bindingResult.hasErrors()) {
            List<ObjectError> errors = bindingResult.getAllErrors();
            firstError = errors.get(0);
        }
        int defaultErrorCode = ApiResponseEnum.ERROR_002.getCode();
        String defaultErrorMsg;
        if (StringUtils.isBlank(resultCodeLocaleMessage.getMessage(defaultErrorCode))){
            defaultErrorMsg = ApiResponseEnum.ERROR_002.getDesc();
        }else {
            defaultErrorMsg = resultCodeLocaleMessage.getMessage(defaultErrorCode);
        }
        ApiResponse apiResponse = ApiResponse.create(defaultErrorCode, defaultErrorMsg);
        if (firstError != null) {
            String errorMsg = firstError.getDefaultMessage();
            if (StringUtils.isNotBlank(errorMsg)) {
                try {
                    LetokenApiResponseEnum errorResCode = LetokenApiResponseEnum.getResponseCode(Integer.parseInt(errorMsg));
                    if (errorResCode != null) {
                        String r = resultCodeLocaleMessage.getMessage(errorResCode.getCode(),null,null,getLocal());
                        if (StringUtils.isBlank(r)){
                            apiResponse = ApiResponse.create(errorResCode.getCode(), errorResCode.getMsg());
                        }else {
                            apiResponse = ApiResponse.create(errorResCode.getCode(), r);
                        }

                    }
                } catch (NumberFormatException e3) {
                    log.error(e.getMessage());
                    apiResponse = ApiResponse.create(defaultErrorCode, errorMsg);
                }
            }
        }
        return apiResponse;
    }

    @ExceptionHandler({Exception.class, RuntimeException.class})
    public ApiResponse handleException(final Exception e) {
        log.error(e.getMessage(),e);
//        if (StringUtils.isBlank(resultCodeLocaleMessage.getMessage(e.getCode()))){
//            return ApiResponse.create(e.getCode(), e.getDesc());
//        }
//        return ApiResponse.create(e.getCode(), resultCodeLocaleMessage.getMessage(e.getCode()));
        ApiServiceException apiServiceException =  new ApiServiceException(ApiResponseEnum.ERROR_008);
        if (e instanceof SQLException || e instanceof DataAccessException){
             apiServiceException = new ApiServiceException(ApiResponseEnum.ERROR_006);
        }
        return ApiResponse.create(apiServiceException.getCode(), resultCodeLocaleMessage.getMessage(apiServiceException.getCode(),null,null,getLocal()));
    }


    private Locale getLocal(){
        String defaultLanguage  =  "zh";
        String defaultCountry = "CN";
        try {
            ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = servletRequestAttributes.getRequest();
            String language = request.getHeader("language");
            if (StringUtils.isNotBlank(language)) {
                String[] arr  = language.split("_");
                if (arr != null && arr.length == 2){
                    return new Locale(arr[0],arr[1]);
                }
            }
        }catch (Exception e){

        }
        return new Locale(defaultLanguage,defaultCountry);


    }

}

//
//
//package com.letoken.platform.pub.advice;
//
//
//
//import com.letoken.platform.pub.enums.ApiResponseEnum;
//import com.letoken.platform.pub.enums.LetokenApiResponseEnum;
//import com.letoken.platform.pub.exception.ApiServiceException;
//import com.letoken.platform.pub.message.LocaleMessage;
//import com.letoken.platform.pub.res.ApiResponse;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.collections.CollectionUtils;
//import org.apache.commons.lang3.StringUtils;
//import org.springframework.dao.DataAccessException;
//import org.springframework.validation.BindingResult;
//import org.springframework.validation.ObjectError;
//import org.springframework.web.bind.MethodArgumentNotValidException;
//import org.springframework.web.bind.annotation.ExceptionHandler;
//import org.springframework.web.bind.annotation.RestController;
//import org.springframework.web.bind.annotation.RestControllerAdvice;
//import org.springframework.web.servlet.support.RequestContextUtils;
//
//import javax.annotation.Resource;
//import javax.servlet.http.HttpServletRequest;
//import java.sql.SQLException;
//import java.util.List;
//
///**
// * ApiServiceExceptionHandler
// *
// * @Author: letokenlabs
// * @Date: 2021/11/23 15:02
// */
//@Slf4j
//@RestControllerAdvice(annotations = {RestController.class})
//public class ApiServiceExceptionHandler {
//
//    @Resource
//    private LocaleMessage resultCodeLocaleMessage;
//
//
//    @ExceptionHandler({ApiServiceException.class})
//    public ApiResponse handleServiceException(HttpServletRequest req, final ApiServiceException e) {
//        log.error(e.getMessage(),e);
////        return ApiResponse.create(e.getCode(), resultCodeLocaleMessage.getMessage(e.getCode(),new Object[0], RequestContextUtils.getLocale(req)));
//        if (StringUtils.isBlank(resultCodeLocaleMessage.getMessage(e.getCode()))){
//            if (StringUtils.isBlank(e.getDesc())){
//                return ApiResponse.create(e.getCode(), e.getMessage());
//            }
//            return ApiResponse.create(e.getCode(), e.getDesc());
//        }
//
//        String desc = resultCodeLocaleMessage.getMessage(e.getCode());
//        if (desc.contains("s%")){
//            Object[] arr = e.getArgs();
//            desc = String.format(desc,arr);
//        }
//
//        return ApiResponse.create(e.getCode(),desc );
//    }
//
//    /**
//     * 参数校验异常拦截
//     *
//     * @param e
//     * @return
//     */
//    @ExceptionHandler(MethodArgumentNotValidException.class)
//    public ApiResponse handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
//        log.error(e.getMessage(),e);
//        BindingResult bindingResult = e.getBindingResult();
//        ObjectError firstError = null;
//        if (bindingResult.hasErrors()) {
//            List<ObjectError> errors = bindingResult.getAllErrors();
//            firstError = errors.get(0);
//        }
//        int defaultErrorCode = ApiResponseEnum.ERROR_002.getCode();
//        String defaultErrorMsg;
//        if (StringUtils.isBlank(resultCodeLocaleMessage.getMessage(defaultErrorCode))){
//            defaultErrorMsg = ApiResponseEnum.ERROR_002.getDesc();
//        }else {
//            defaultErrorMsg = resultCodeLocaleMessage.getMessage(defaultErrorCode);
//        }
//        ApiResponse apiResponse = ApiResponse.create(defaultErrorCode, defaultErrorMsg);
//        if (firstError != null) {
//            String errorMsg = firstError.getDefaultMessage();
//            if (StringUtils.isNotBlank(errorMsg)) {
//                try {
//                    LetokenApiResponseEnum errorResCode = LetokenApiResponseEnum.getResponseCode(Integer.parseInt(errorMsg));
//                    if (errorResCode != null) {
//                        if (StringUtils.isBlank(resultCodeLocaleMessage.getMessage(errorResCode.getCode()))){
//                            apiResponse = ApiResponse.create(errorResCode.getCode(), errorResCode.getMsg());
//                        }else {
//                            apiResponse = ApiResponse.create(errorResCode.getCode(), resultCodeLocaleMessage.getMessage(errorResCode.getCode()));
//                        }
//
//                    }
//                } catch (NumberFormatException e3) {
//                    log.error(e.getMessage());
//                    apiResponse = ApiResponse.create(defaultErrorCode, errorMsg);
//                }
//            }
//        }
//        return apiResponse;
//    }
//
//    @ExceptionHandler({Exception.class, RuntimeException.class})
//    public ApiResponse handleException(final Exception e) {
//        log.error(e.getMessage(),e);
////        if (StringUtils.isBlank(resultCodeLocaleMessage.getMessage(e.getCode()))){
////            return ApiResponse.create(e.getCode(), e.getDesc());
////        }
////        return ApiResponse.create(e.getCode(), resultCodeLocaleMessage.getMessage(e.getCode()));
//        ApiServiceException apiServiceException =  new ApiServiceException(ApiResponseEnum.ERROR_008);
//        if (e instanceof SQLException || e instanceof DataAccessException){
//            apiServiceException = new ApiServiceException(ApiResponseEnum.ERROR_006);
//        }
//        return ApiResponse.create(apiServiceException.getCode(), resultCodeLocaleMessage.getMessage(apiServiceException.getCode()));
//    }
//}
